﻿using System;
using System.Windows.Forms;
using CookComputing.XmlRpc;

namespace SimpleMediaManager.OSDB
{
    public class Api
    {
        private const string API_URL = "http://api.opensubtitles.org/xml-rpc";
        private const string LANGUAGE = "en";
        private const string USER_AGENT = "Simple Media Manager v1.0";

        private IOpenSubtitles proxy;

        public string Username { get; set; }
        public string Password { get; set; }
        public string Token { get; internal set; }
        public String LastResponseCode { get; internal set; }
        public double LastResponseTime { get; internal set; }

        [XmlRpcUrl(API_URL)]
        public interface IOpenSubtitles : IXmlRpcProxy
        {
            [XmlRpcMethod("ServerInfo")]
            XmlRpcStruct GetServerInfo();

            [XmlRpcMethod("LogIn")]
            XmlRpcStruct Login(string username, string password, string language, string useragent);

            [XmlRpcMethod("LogOut")]
            XmlRpcStruct Logout(string token);

            [XmlRpcMethod("NoOperation")]
            XmlRpcStruct NoOperation(string token);

            [XmlRpcMethod("CheckMovieHash")]
            XmlRpcStruct CheckMovieHash(string token, params object[] parameters);

            [XmlRpcMethod("SearchSubtitles")]
            XmlRpcStruct SearchSubtitles(string token, params object[] parameters);

            [XmlRpcMethod("DownloadSubtitles")]
            XmlRpcStruct DownloadSubtitles(string token, int[] IDSubtitleFile);
        }

        public Api(string username, string password)
        {
            this.Username = username;
            this.Password = password;

            try
            {
                proxy = XmlRpcProxyGen.Create<IOpenSubtitles>();
                proxy.KeepAlive = false;

                if (!Login(this.Username, this.Password, LANGUAGE, USER_AGENT))
                {
                    MessageBox.Show("Login failed: " + this.LastResponseCode.ToString());
                    return;
                }

                if (!NoOperation())
                {
                    MessageBox.Show("Error code: " + this.LastResponseCode.ToString());
                    return;
                }

                ServerInfo a = GetServerInfo();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message);
            }
        }

        public ServerInfo GetServerInfo()
        {
            XmlRpcStruct responseStruct = proxy.GetServerInfo();

            ServerInfo serverInfo = new ServerInfo();
            serverInfo.Application = responseStruct["application"].ToString();
            serverInfo.WebsiteUrl = responseStruct["website_url"].ToString();
            serverInfo.Contact = responseStruct["contact"].ToString();
            serverInfo.XmlRpcVersion = responseStruct["xmlrpc_version"].ToString();
            serverInfo.XmlRpcUrl = responseStruct["xmlrpc_url"].ToString();
            serverInfo.Seconds = responseStruct["users_max_alltime"].ToString();
            serverInfo.TotalMoviesCount = int.Parse(responseStruct["movies_total"].ToString());
            serverInfo.MoviesAka = int.Parse(responseStruct["movies_aka"].ToString());
            serverInfo.TotalSubtitleFiles = int.Parse(responseStruct["subs_subtitle_files"].ToString());
            serverInfo.TotalSubtitlesLanguages = int.Parse(responseStruct["total_subtitles_languages"].ToString());
            serverInfo.TotalSubsDownloaded = int.Parse(responseStruct["subs_downloads"].ToString());
            serverInfo.UsersRegistred = int.Parse(responseStruct["users_registered"].ToString());
            serverInfo.UsersLoggedIn = int.Parse(responseStruct["users_loggedin"].ToString());
            serverInfo.UsersOnlineProgram = int.Parse(responseStruct["users_online_program"].ToString());
            serverInfo.TotalUsersOnline = int.Parse(responseStruct["users_online_total"].ToString());
            serverInfo.UsersMaxAllTime = int.Parse(responseStruct["users_max_alltime"].ToString());

            return serverInfo;
        }

        public bool Login(string username, string password, string language, string userAgent)
        {
            XmlRpcStruct responseStruct = proxy.Login(username, password, language, userAgent);

            this.LastResponseCode = (string)responseStruct["status"];
            this.LastResponseTime = Convert.ToDouble(responseStruct["seconds"]);

            if ((!String.IsNullOrEmpty(this.LastResponseCode)) && this.LastResponseCode.Equals("200 OK"))
            {
                this.Token = (string)responseStruct["token"];

                return true;
            }

            return false;
        }

        public bool Logout(string token)
        {
            XmlRpcStruct ResponseStruct = proxy.Logout(this.Token);

            this.LastResponseCode = (string)ResponseStruct["status"];
            this.LastResponseTime = Convert.ToDouble(ResponseStruct["seconds"]);
            this.Token = null;

            return this.LastResponseCode.Equals("200 OK");
        }

        public bool NoOperation()
        {
            XmlRpcStruct ResponseStruct = proxy.NoOperation(this.Token);

            this.LastResponseCode = (string)ResponseStruct["status"];
            this.LastResponseTime = Convert.ToDouble(ResponseStruct["seconds"]);

            return this.LastResponseCode.Equals("200 OK");
        }
    }
}
